import groovy.jmx.builder.JmxBuilder
import javax.management.MBeanServer
import javax.management.ObjectName

class JmxOperationFactoryTest extends GroovyTestCase {
    def jmx

    void testInitializtion() {
        jmx = new JmxBuilder()
        assertTrue jmx != null
    }

    void setUp() {
        jmx = new JmxBuilder()
    }

    void testJmxOperationFactoryExplicit() {
        def observed = new ExposedTestBean(id: "TestBean")
        MBeanServer parent = jmx.export {
            bean(observed) {
                name("jmxBuilder:type=bean")
                description("This is a test bean")
                operation('name': "toss", 'desc': "toss operation") {
                    parameter('type': 'int', 'name': "distance", 'desc': "distance for toss")
                    parameter('type': 'java.lang.Object', 'name': "force", 'desc': "force to use")
                }
                operation('name': "stretch", 'desc': "This operation stretches object")
                constructor("name": "ExposedTestBean") {
                    parameter(type: "int", 'name': "size", 'desc': "size")
                    parameter(type: "int", 'name': "length", 'desc': "length")
                }
            }
        }

        assert parent
        assert parent.isRegistered(new ObjectName("jmxBuilder:type=bean"))
        assert parent.isRegistered(new ObjectName("jmxBuilder:type=bean"))
        assert parent.getMBeanInfo(new ObjectName("jmxBuilder:type=bean")).operations.size() == 2

        assert parent.getMBeanInfo(new ObjectName("jmxBuilder:type=bean")).operations[0].name.equals("stretch")

        assert parent.getMBeanInfo(new ObjectName("jmxBuilder:type=bean")).operations[1].name.equals("toss")
        assert parent.getMBeanInfo(new ObjectName("jmxBuilder:type=bean")).operations[1].returnType.equals("java.lang.Object")
        assert parent.getMBeanInfo(new ObjectName("jmxBuilder:type=bean")).operations[1].signature.size() == 2
        assert parent.getMBeanInfo(new ObjectName("jmxBuilder:type=bean")).operations[1].signature[0].name == "distance"
        assert parent.getMBeanInfo(new ObjectName("jmxBuilder:type=bean")).operations[1].signature[1].name == "force"

        assert parent.getMBeanInfo(new ObjectName("jmxBuilder:type=bean")).constructors[0].name.equals("ExposedTestBean")
        assert parent.getMBeanInfo(new ObjectName("jmxBuilder:type=bean")).constructors[0].signature.size() == 2
        assert parent.getMBeanInfo(new ObjectName("jmxBuilder:type=bean")).constructors[0].signature[0].name == "size"
        assert parent.getMBeanInfo(new ObjectName("jmxBuilder:type=bean")).constructors[0].signature[1].name == "length"

        parent.unregisterMBean(new ObjectName("jmxBuilder:type=bean"))
    }


    void testJmxMBeanFactoryImplicit() {
        def observed = new TestJavaBean()
        MBeanServer parent = jmx.export {
            bean(object: observed, name: "jmxBuilder:type=bean")
        }

        assert parent
        assert parent.isRegistered(new ObjectName("jmxBuilder:type=bean"))
        assert parent.isRegistered(new ObjectName("jmxBuilder:type=bean"))
        assert parent.getMBeanInfo(new ObjectName("jmxBuilder:type=bean")).operations.size() == 2

        parent.unregisterMBean new ObjectName("jmxBuilder:type=bean")
    }
}